/*
 * @Description: blob处理
 * @Author: qingyang
 * @Date: 2021-03-10 09:39:11
 * @LastEditors: chenju
 * @LastEditTime: 2022-01-25 14:58:23
 */

import { Base64 } from 'js-base64';
import { ElMessage } from 'element-plus/lib/components';
import axios from 'axios';
import { isJSON } from './index';

// mine类型对应表
const mineTypeMap: any = {
  xls: 'application/vnd.ms-excel application/x-excel',
  xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  doc: 'application/msword',
  docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  ppt: 'application/vnd.ms-powerpoint',
  pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  zip: 'application/x-zip-compressed',
  rar: 'application/octet-stream',
  pdf: 'application/pdf',
  csv: 'application/csv'
};

/**
 * url下载并且重命名
 * @param {string} url
 * @param {String} filename
 */

export const downUrlToFile = (url: string, filename: string): void => {
  const mineArr = filename.split('.');
  let propFilename = '',
    propSuffix = '';
  if (mineArr.length >= 2) {
    propSuffix = mineArr[mineArr.length - 1];
    mineArr.pop();
    propFilename = mineArr.join('.');
  } else {
    propFilename = filename;
    propSuffix = '';
  }

  axios
    .get(url, {
      responseType: 'blob'
    })
    .then((res: any) => {
      downloadFile(res.data, propFilename, propSuffix);
    })
    .catch(() => {
      ElMessage.error('文件下载失败，请刷新页面后重试！');
    });
};
/**
 * 下载二级制流文件
 * @param {Blob} data
 * @param {String} filename
 */
export const downloadBlobData = (data: Blob, filename: string) => {
  // for IE
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(data, filename);
  }
  // for Non-IE (chrome, firefox etc.)
  else {
    const downloadUrl = window.URL.createObjectURL(data);
    const anchor = document.createElement('a');
    anchor.target = '_blank'; // 兼容firefox
    document.body.appendChild(anchor); // 兼容firefox
    anchor.href = downloadUrl;
    anchor.download = filename;
    anchor.click();
    window.URL.revokeObjectURL(downloadUrl);
    document.body.removeChild(anchor); // 兼容firefox
  }
};

export const downloadFile = (
  data: Blob,
  filename = '导出文件',
  suffix = 'xlsx',
  showMessage = false
) => {
  return new Promise((resolve, reject) => {
    const size = data.size;
    if (!size) {
      showMessage && ElMessage.error('文件导出异常！');
      return reject('文件导出异常');
    }
    const blob = data;
    // 解析二级制流
    const reader = new FileReader();
    reader.readAsDataURL(blob);
    // 二级制流解析完成
    reader.onload = (e: any) => {
      const result = e.target.result;
      const base64Str = result.split('base64,')[1];
      // 结果是个json，说明是服务端报错
      if (isJSON(Base64.decode(base64Str))) {
        const res = JSON.parse(Base64.decode(base64Str));
        const errMsg = res.msg || '异常错误';
        showMessage && ElMessage.error(errMsg);
        reject(errMsg);
      } else {
        // 不是个json数组 说明是二级制流
        const data = new Blob([blob], { type: mineTypeMap[suffix] });
        // 下载文件
        downloadBlobData(data, `${filename}.${suffix}`);
        resolve(true);
      }
    };
    // 二级制流解析失败
    reader.onerror = errMsg => {
      showMessage && ElMessage.error('文件导出失败，请稍后重试');
      reject(errMsg);
    };
  });
};

/**
 * 获取文件的后缀名
 * @param url 链接
 */
export function getFileSuffix(url: string): string {
  // 1. 去掉？后面部分
  const urlArr = url.split('?');
  // 2. 去掉.前面部分
  if (urlArr[0].indexOf('.') > -1) {
    const fileArr = urlArr[0].split('.');
    // 3. 数组最后一个元素就是后缀名
    const suffix = fileArr.pop();
    if (suffix) {
      return suffix;
    } else {
      return '';
    }
  } else {
    return '';
  }
}

/**
 * 根据文件url获取文件名和文件后缀名
 * @param fileUrl
 * @returns
 */
export function getFileNameAndSuffixByUrl(fileUrl: string) {
  const fileUrlArr = fileUrl.split('/');
  const filenameAll = fileUrlArr[fileUrlArr.length - 1];
  const filenameAllArr = filenameAll.split('.');
  const suffix = filenameAllArr.pop();
  const filename = filenameAllArr.join('.');
  return {
    filename,
    suffix
  };
}
